home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Speccy ClassiX 1998
/
Speccy ClassiX 98.iso
/
amiga_system
/
the_aminet
/
dev
/
gcc
/
ixemulsrc.lha
/
ixemul-41.4
/
library
/
__tioctl.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-05-28
|
7KB
|
292 lines
/*
* This file is part of ixemul.library for the Amiga.
* Copyright (C) 1991, 1992 Markus M. Wild
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* __tioctl.c,v 1.1.1.1 1994/04/04 04:30:13 amiga Exp
*
* __tioctl.c,v
* Revision 1.1.1.1 1994/04/04 04:30:13 amiga
* Initial CVS check in.
*
* Revision 1.5 1993/11/05 21:51:08 mw
* seems I got oldstyle tty handling oposite way..
*
* Revision 1.4 1992/08/09 20:39:01 amiga
* add a cast to get rid of a warning
*
* Revision 1.3 1992/07/04 19:07:25 mwild
* send DISK_INFO packet with synchronous port, async delivery seems to be
* broken with CNC:
*
* Revision 1.2 1992/06/08 02:36:00 mwild
* fix TIOCGWINSZ, row/column was off by one
*
* Revision 1.1 1992/05/14 19:55:40 mwild
* Initial revision
*
*/
#define KERNEL
#include "ixemul.h"
#include "kprintf.h"
#include <sgtty.h>
#define OB0 B0
#define OB50 B50
#define OB75 B75
#define OB110 B110
#define OB134 B134
#define OB150 B150
#define OB200 B200
#define OB300 B300
#define OB600 B600
#define OB1200 B1200
#define OB1800 B1800
#define OB2400 B2400
#define OB4800 B4800
#define OB9600 B9600
#define OEXTA EXTA
#define OEXTB EXTB
#undef B0
#undef B50
#undef B75
#undef B110
#undef B134
#undef B150
#undef B200
#undef B300
#undef B600
#undef B1200
#undef B1800
#undef B2400
#undef B4800
#undef B9600
#undef EXTA
#undef EXTB
#include <sys/termios.h>
#include <ctype.h>
#include <devices/conunit.h>
#if __GNUC__ != 2
#define alloca __builtin_alloca
#endif
/* IOCTLs on "interactive" files */
int
__tioctl(struct file *f, unsigned int cmd, unsigned int inout,
unsigned int arglen, unsigned int arg)
{
int omask, result, err;
omask = syscall (SYS_sigsetmask, ~0);
__get_file (f);
result = -1;
if (/*!IsInteractive(CTOBPTR(f->f_fh))*/ ! f->f_fh->fh_Port)
{
err = ENOTTY;
goto ret;
}
switch (cmd)
{
case TIOCGETA:
{
struct termios *t = (struct termios *)arg;
unsigned char *cp;
t->c_iflag = IGNBRK|IGNPAR|ICRNL|IXON;
t->c_oflag = (f->f_flags & FTTYRAW) ? 0 : OPOST|ONLCR;
t->c_cflag = CS8|CLOCAL;
t->c_ispeed=
t->c_ospeed= B38400;
/* Conman does ECHOCTL, Commo doesn't.. I use Conman:-)) */
t->c_lflag = ECHOCTL|((f->f_flags & FTTYRAW)?0:ICANON|ECHO);
/* t->c_line = 0; */
cp = t->c_cc;
cp[VSTART] = 'q' & 31;
cp[VSTOP] = 's' & 31;
cp[VSUSP] = 0; /* sneef.. would that be nice... */
cp[VDSUSP] = 0;
cp[VREPRINT] = 0;
cp[VDISCARD] = 'x' & 31;
cp[VWERASE] = 0;
cp[VLNEXT] = 0;
cp[VSTATUS] = 0;
cp[VINTR] = 3;
cp[VQUIT] = 0;
cp[VERASE] = 8;
cp[VKILL] = 'x' & 31;
cp[VEOF] = '\\' & 31;
cp[VEOL] = 10;
cp[VEOL2] = 0;
result = 0;
goto ret;
}
case TIOCSETA:
case TIOCSETAW:
case TIOCSETAF:
{
struct termios *t = (struct termios *)arg;
int makeraw;
makeraw = (t->c_lflag & (ICANON | ECHO)) != (ICANON | ECHO);
/* the only thing that counts so far.. if ICANON is disabled,
* we disable ECHO too, no matter what the user wanted, and
* send a RAW-packet.. */
if (!makeraw && (f->f_flags & FTTYRAW))
{
f->f_flags &= ~FTTYRAW;
__wait_packet(&f->f_sp);
SendPacket1(f,__rwport,ACTION_SCREEN_MODE,0);
__wait_packet(&f->f_sp);
}
else if (makeraw && !(f->f_flags & FTTYRAW))
{
f->f_flags |= FTTYRAW;
__wait_packet(&f->f_sp);
SendPacket1(f,__rwport,ACTION_SCREEN_MODE,-1);
__wait_packet(&f->f_sp);
}
result = 0;
goto ret;
}
case TIOCGETP:
{
struct sgttyb *s = (struct sgttyb *)arg;
s->sg_erase = 8;
s->sg_kill = 'x' & 31;
s->sg_flags = ODDP|EVENP|ANYP|
((f->f_flags&FTTYRAW) ? (CBREAK|RAW) : (ECHO|CRMOD));
s->sg_ispeed =
s->sg_ospeed = OEXTB;
result = 0;
goto ret;
}
case TIOCSETN:
case TIOCSETP:
{
struct sgttyb *s = (struct sgttyb *)arg;
if (!(s->sg_flags & (RAW|CBREAK)) /*&& (f->f_flags & FTTYRAW)*/)
{
f->f_flags &= ~FTTYRAW;
__wait_packet(&f->f_sp);
SendPacket1(f,__rwport,ACTION_SCREEN_MODE,0);
__wait_packet(&f->f_sp);
}
else if ((s->sg_flags & (RAW|CBREAK)) /*&& !(f->f_flags & FTTYRAW)*/)
{
f->f_flags |= FTTYRAW;
SendPacket1(f,__rwport,ACTION_SCREEN_MODE,-1);
__wait_packet(&f->f_sp);
}
result = 0;
goto ret;
}
case TIOCGWINSZ:
{
struct winsize *ws = (struct winsize *) arg;
struct ConUnit *cu;
struct IOStdReq *ios;
struct InfoData *info;
struct Window *w;
err = EINVAL; /* default */
info = alloca (sizeof (struct InfoData) + 2);
info = LONG_ALIGN (info);
bzero (info, sizeof (struct InfoData));
/* VERY! strange.. CNC: won't act on the packet if it sent with the
async port as reply port! The error is OBJECT_IN_USE (202)... */
__wait_packet (&f->f_sp);
LastResult (f) = 0; LastError (f) = 0;
SendPacket1 (f, u.u_sync_mp, ACTION_DISK_INFO, CTOBPTR (info));
__wait_sync_packet (&f->f_sp);
if (LastResult (f) != -1)
{
/* syscall (SYS_strncmp, "ACTION_DISK_INFO failed!", "", LastError(f));*/
goto ret;
}
w = (struct Window *) info->id_VolumeNode;
if (! w)
{
/* syscall (SYS_index, "No window in InfoData structure!", 0);*/
goto ret;
}
/* this information is from DevCon notes, not from the Bantam book */
ios = (struct IOStdReq *) info->id_InUse;
if (! ios || ((int)ios & 1))
{
/* syscall (SYS_index, "invalid ConUnit pointer in InfoData!", 0);*/
goto ret;
}
cu = (struct ConUnit *) ios->io_Unit;
if (!cu)
{
/* syscall (SYS_index, "no ConUnit pointer in InfoData!", 0);*/
goto ret;
}
/* paranoid check.. */
if (cu->cu_Window != w)
{
/* syscall (SYS_index, "incompatible ConUnit pointer in InfoData!", 0);*/
goto ret;
}
ws->ws_xpixel = w->Width - w->BorderLeft - w->BorderRight;
ws->ws_ypixel = w->Height - w->BorderTop - w->BorderBottom;
ws->ws_col = cu->cu_XMax + 1; /* Thanks Rob! those values are off */
ws->ws_row = cu->cu_YMax + 1; /* by one! */
result = 0;
goto ret;
}
case TIOCOUTQ:
{
int *count = (int *)arg;
*count = 0;
result = 0;
goto ret;
}
case TIOCSWINSZ:
/* should I really try to resize the window ?? */
default:
/* this is no error, but nevertheless we don't take any actions.. */
result = 0;
goto ret;
}
ret:
LastResult(f) = 0;
__release_file (f);
syscall (SYS_sigsetmask, omask);
errno = err;
KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
return result;
}